﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Interop.Excel;
using System.Drawing;

namespace QExcel
{
    public class QColumn : QItem
    {
        public QColumn()
        {
        }

        /// <summary>
        /// 列中显示的正文
        /// </summary>
        public string Text
        {
            get;
            set;
        }

        /// <summary>
        /// 所属表
        /// </summary>
        public QTable Table
        {
            get;
            set;
        }

        /// <summary>
        /// 是否汇总列
        /// </summary>
        public bool IsCount
        {
            get;
            set;
        }

        private int width = 15;
        /// <summary>
        /// 该列是否显示
        /// </summary>
        public int Width
        {
            get
            {
                return width;
            }
            set
            {
                width = value;
            }
        }

        /// <summary>
        /// 正文背景色
        /// </summary>
        public Color ContentBgColor
        {
            get;
            set;
        }

        /// <summary>
        /// 公式
        /// </summary>
        public string Formula
        {
            get;
            set;
        }

        /// <summary>
        /// 别名
        /// </summary>
        public string Name
        {
            get;
            set;
        }

        /// <summary>
        /// 列格式
        /// </summary>
        public string NumberFormatLocal
        {
            get;
            set;
        }

        private List<QColumn> leafColumns = new List<QColumn>();
        /// <summary>
        /// 子列
        /// </summary>
        public List<QColumn> LeafColumns
        {
            get
            {
                return leafColumns;
            }
        }

        /// <summary>
        /// 父列
        /// </summary>
        public QColumn ParentColumn
        {
            get;
            set;
        }

        public int curIndex =0;
        /// <summary>
        /// 设置当前列的索引值
        /// </summary>
        /// <param name="index"></param>
        public void SetCurIndex(int index)
        {
            this.curIndex = index;
        }

        /// <summary>
        /// 添加子列
        /// </summary>
        /// <param name="clumn"></param>
        public virtual void AddColumn(QColumn clumn)
        {
            clumn.curIndex = this.leafColumns.Count;
            this.leafColumns.Add(clumn);
            clumn.Table = this.Table;
            clumn.ParentColumn = this;
        }

        /// <summary>
        /// 获取实际的索引值
        /// </summary>
        public int Index
        {
            get
            {
                int indexValue = 0;
                if (this.ParentColumn != null)
                {
                    foreach (QColumn qclumn in this.ParentColumn.leafColumns)
                    {
                        if (qclumn.curIndex < this.curIndex)
                        {
                            indexValue += qclumn.ColCount;
                        }
                    }
                    return this.ParentColumn.Index + indexValue;
                }
                else
                {
                    foreach (QColumn column in this.Table.Columns.Columns)
                    {
                        if (column.curIndex < this.curIndex)
                        {
                            indexValue += column.ColCount;
                        }
                    }
                    return indexValue;
                }
            }
        }

        /// <summary>
        /// 获取该列总深度
        /// </summary>
        public int Depth
        {
            get
            {
                return this.GetColumnsDepth(this.leafColumns);
            }
        }

        /// <summary>
        /// 递归得到列深度
        /// </summary>
        /// <param name="columns"></param>
        /// <returns></returns>
        private int GetColumnsDepth(List<QColumn> columns)
        {
            if (this.leafColumns.Count == 0)
            {
                return 1;
            }
            else
            {
                int count = 0;

                foreach (QColumn clumn in columns)
                {
                    if (count < clumn.Depth)
                    {
                        count = clumn.Depth;
                    }
                }
                return count + 1;
            }
        }

        /// <summary>
        /// 获取列当前深度
        /// </summary>
        public int CurDepth
        {
            get
            {
                curDepth = 1;
                this.GetCurDepth(this);
                return curDepth;
            }
        }

        int curDepth = 1;
        /// <summary>
        /// 递归得到当前列深度
        /// </summary>
        /// <param name="column"></param>
        private void GetCurDepth(QColumn column)
        {
            if (column.ParentColumn != null)
            {
                curDepth++;
                this.GetCurDepth(column.ParentColumn);
            }
        }

        /// <summary>
        /// 获取子列数
        /// </summary>
        public int ColCount
        {
            get
            {
                colCount = 0;
                this.GetColumnsCount(this);
                return colCount;
            }
        }

        int colCount = 0;
        /// <summary>
        /// 递归得到子列数
        /// </summary>
        /// <param name="clumn"></param>
        private void GetColumnsCount(QColumn clumn)
        {
            if (clumn.LeafColumns.Count == 0)
            {
                colCount++;
            }
            else
            {
                foreach (QColumn child in clumn.leafColumns)
                    this.GetColumnsCount(child);
            }
        }

        public override void Output()
        {

        }

        /// <summary>
        /// 输出
        /// </summary>
        /// <param name="startRow"></param>
        /// <param name="startClomn"></param>
        /// <param name="rowDepth"></param>
        public void Output(int startRow, int startClomn, int rowDepth)
        {
            Worksheet workSheet = this.Table.Sheet.WorkSeet;
            int endRow = this.CurDepth;
            if (this.leafColumns.Count == 0 && endRow == 1 && endRow != rowDepth)
            {
                endRow = rowDepth;
            }
            else if (this.leafColumns.Count == 0 && endRow != rowDepth)
            {
                endRow = rowDepth;
            }
            Range range = workSheet.get_Range(workSheet.Cells[startRow + this.CurDepth - 1, startClomn + this.Index], workSheet.Cells[startRow + endRow - 1, startClomn + this.Index + ColCount - 1]);
            range.Select();
            range.Merge(Type.Missing);
            this.IsBold = true;
            this.FontSize = this.Table.HeadFontSize;
            this.SetStyle(range);
            range.Value2 = Text;
            workSheet.Names.Add(this.Name, range.Address);

            range.ColumnWidth = this.width;
            this.SetColumnNumberFormat(startRow, startClomn);
            foreach (QColumn leafCol in this.leafColumns)
            {
                leafCol.Table = this.Table;
                leafCol.Sheet = this.Sheet;
                leafCol.Output(startRow, startClomn, rowDepth);
            }
        }

        /// <summary>
        /// 设置格式
        /// </summary>
        /// <param name="startRow"></param>
        /// <param name="startCol"></param>
        private void SetColumnNumberFormat(int startRow, int startCol)
        {
            if (!string.IsNullOrEmpty(this.NumberFormatLocal))
            {
                Worksheet sheet = this.Table.Sheet.WorkSeet;
                Range range = sheet.get_Range(sheet.Cells[startRow + this.Table.Columns.Depth, this.Index + startCol], sheet.Cells[startRow + this.Table.Columns.Depth + this.Table.Rows.Count, this.Index + startCol]);
                range.NumberFormat = this.NumberFormatLocal;
            }
        }
    }
}
